package com.ctl.algorithm;

import java.util.Random;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {

    static class TaskThread extends Thread {

        CyclicBarrier barrier;

        public TaskThread(CyclicBarrier barrier) {
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(new Random().nextInt(100));
                System.out.println(getName() + " 到达栅栏 A\t"+barrier.getNumberWaiting());
                barrier.await(); //barrier可重复使用n个都到达后重新计算
                System.out.println(getName() + " 冲破栅栏 A\t"+barrier.getNumberWaiting());

                Thread.sleep(new Random().nextInt(200));
                System.out.println(getName() + " 到达栅栏 B\t"+barrier.getNumberWaiting());
                barrier.await();
                System.out.println(getName() + " 冲破栅栏 B\t"+barrier.getNumberWaiting());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int threadNum = 5;
        CyclicBarrier barrier = new CyclicBarrier(threadNum, () -> {
            System.out.println(Thread.currentThread().getName() + " 完成最后任务");
        });
        barrier = new CyclicBarrier(threadNum);
        for (int i = 0; i < threadNum; i++) {
            new TaskThread(barrier).start();
        }
    }

}
//Thread-3 到达栅栏 A	0
//Thread-2 到达栅栏 A	1
//Thread-4 到达栅栏 A	2
//Thread-1 到达栅栏 A	3
//Thread-0 到达栅栏 A	4

//Thread-0 冲破栅栏 A	0
//Thread-3 冲破栅栏 A	0
//Thread-4 冲破栅栏 A	0
//Thread-2 冲破栅栏 A	0
//Thread-1 冲破栅栏 A	0

//Thread-2 到达栅栏 B	0
//Thread-3 到达栅栏 B	1
//Thread-1 到达栅栏 B	2
//Thread-0 到达栅栏 B	3
//Thread-4 到达栅栏 B	4

//Thread-4 冲破栅栏 B	0
//Thread-2 冲破栅栏 B	0
//Thread-1 冲破栅栏 B	0
//Thread-3 冲破栅栏 B	0
//Thread-0 冲破栅栏 B	0